import asyncio
import subprocess
import argparse

async def services_update(dir, username, password, host, project, queue):
    '''curl的超时设置都是默认,如网络状态不好,包的更新就会被跳过或失败,
    好在可以在网页中查看到是否都更新完成,没更新的可用手动更新。'''
    while True:
        name = await queue.get()
        if name is not None:
            proc= await asyncio.create_subprocess_shell(f"curl -u {username}:{password} -X POST  https://{host}/source/{project}/{name}?cmd=runservice")
            await proc.wait()
            await asyncio.sleep(0)

            proc= await asyncio.create_subprocess_shell(f"curl  -u {username}:{password} -X POST https://{host}/source/{project}/{name}?cmd=waitservice")
            await proc.wait() # 等待后端完成该service任务,以免发送任务过多
            await asyncio.sleep(0)
        else:
            pass
        queue.task_done()


async def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('username')
    parser.add_argument('password')
    parser.add_argument('host') # 注意与下方osc命令配置的访问服务器域名一致
    parser.add_argument('project')
    args = parser.parse_args()
    project = args.project
    if not project:
        exit(1)

    queue = asyncio.Queue()
    lists: bytes = subprocess.run(['osc', 'list', project],capture_output=True).stdout
    for name in lists.splitlines(): 
        name = name.decode('UTF-8')
        queue.put_nowait(name) # osc产生的工程包清单信息放入处理队列

    tasks = []
    for i in range(20): # 并行执行数量,第一次测试运行改为,如果没异常,然后改大值正常跑。
        task = asyncio.create_task(services_update(f'osc-{i}', args.username, args.password, args.host, project, queue))
        tasks.append(task)

    await queue.join()

    for task in tasks:
        task.cancel()
    await asyncio.gather(*tasks, return_exceptions=True)

asyncio.run(main())